home *** CD-ROM | disk | FTP | other *** search
- #include "config.h"
- #include "lisp.h"
- #include "termchar.h"
- #include "frame.h"
-
- #include <stdio.h>
- #include <errno.h>
- #include <sys/time.h>
- #include <internal/files.h>
- #include <internal/vars.h>
-
- #undef LONGBITS
-
- #include <exec/types.h>
- #include <dos/dos.h>
- #include <proto/exec.h>
-
- #include "amiga.h"
- #include "termhooks.h"
-
- #ifdef USE_PROTOS
- #include "protos.h"
- #endif
-
- static int term_initialised;
- ULONG inputsig;
-
- /* A few tty system dependent routines unused on the Amiga */
-
- setpgrp_of_tty(int pid) {}
- init_sigio() {}
- reset_sigio() {}
- request_sigio() {}
- unrequest_sigio() {}
-
- /* Return nonzero if safe to use tabs in output.
- At the time this is called, init_sys_modes has not been done yet. */
-
- tabs_safe_p()
- {
- if (noninteractive)
- return 1;
-
- return 0; /* Not safe on Amiga !? */
- }
-
- /* Get terminal size from system.
- Store number of lines into *heightp and width into *widthp.
- If zero or a negative number is stored, the value is not valid. */
-
- get_frame_size (widthp, heightp)
- int *widthp, *heightp;
- {
- #ifdef MULTI_FRAME
- CHFIXME selected_frame below ok?
- #endif
- if (term_initialised && !inhibit_window_system)
- amiga_get_window_size(selected_frame, widthp, heightp);
- else /* We don't known what size the terminal is */
- {
- *widthp = 0;
- *heightp = 0;
- }
- }
-
- init_baud_rate ()
- {
- if (noninteractive || !term_initialised) baud_rate = 1200;
- else if (!inhibit_window_system) baud_rate = 38400;
- else baud_rate = serial_baud_rate();
- }
-
- void check_intuition ()
- {
- if (noninteractive || inhibit_window_system)
- error ("You aren't using a window.");
- }
-
- #define TTYBUFSIZE 256 /* Same size as kbd_buffer */
- static char ttybuf[TTYBUFSIZE];
-
- #define NEW_KBD /* use event queue for sending key strokes to emacs */
-
- static int tty_count;
- #ifndef NEW_KBD
- #define TTYPUT(c) { if (tty_count < TTYBUFSIZE) ttybuf[tty_count++] = c; }
- #else
- #define TTYPUT(c) \
- {\
- event.kind = ascii_keystroke; \
- event.code = c; \
- event.modifiers = 0; \
- event.frame_or_window = selected_frame; \
- gettimeofday (&tv, NULL); \
- event.timestamp = tv.tv_usec; \
- kbd_buffer_store_event (&event); \
- set_mouse_event_pending(); /* wakeup emacs */ \
- }
- #define FTTYPUT(c, qual) \
- {\
- event.kind = non_ascii_keystroke; \
- event.code = c; \
- event.modifiers = qual; \
- event.frame_or_window = selected_frame; \
- gettimeofday (&tv, NULL); \
- event.timestamp = tv.tv_usec; \
- kbd_buffer_store_event (&event); \
- set_mouse_event_pending(); /* wakeup emacs */ \
- }
- #endif
-
- static int interrupt_char;
-
- /*
- * CHFIXME: will the event scheme break serial support? Add mode dependant code?
- */
-
- void enque(unsigned int c, int metaOrQual, int fkey)
-
- /* place input keys in keyboard buffer
-
- was:
- If high bit is set, precede character with ^Q (hack).
- If meta is true, set high bit.
- If both the high bit & meta are true, we have a problem. Ignore it.
- If c == AMIGASEQ (256) enqueue the amiga sequence introducer (C-x C-^)
- now:
- If meta is true, precede key with ESC if key isn\'t ESC.
- Pass high bit as-is.
- If c == AMIGASEQ (256) enqueue the amiga sequence introducer (C-x C-^)
- if fkey is true meta contains full (emacs) qualifier mask and
- c is a non_ascii_event
- */
- {
- #ifdef NEW_KBD
- struct input_event event;
- struct timeval tv;
- #endif
-
- if(fkey)
- {
- FTTYPUT(c, metaOrQual);
- }
- /* Hack CSI to be AMIGASEQ (to allow defining function keys, etc) */
- else if (c == 0233 || c == AMIGASEQ)
- {
- TTYPUT('x' & 037);
- TTYPUT('^' & 037);
- }
- else
- #if 0 /* test ordinary 8 bit */
- if (c >= 0200) /* Special character, precede with ^Q */
- {
- TTYPUT('q' & 037);
- TTYPUT(c);
- }
- else
- #endif
- {
- #if 0
- if (meta) c |= 0200;
- #else
- if(metaOrQual && c != 0x1B) TTYPUT(0x1B); /* ESC */
- #endif
- if (c == interrupt_char) Signal((struct Task *)_us, SIGBREAKF_CTRL_C);
- else TTYPUT(c);
- }
- }
-
- int get_ttycount(void)
- {
- return tty_count;
- }
-
- init_sys_modes ()
- {
- extern int quit_char;
-
- if (noninteractive)
- return;
-
- if (inhibit_window_system) clear_frame();
-
- interrupt_char = quit_char;
- if (!inhibit_window_system) setup_intchar(interrupt_char);
- }
-
- reset_sys_modes ()
- {
- if (noninteractive)
- {
- fflush (stdout);
- return;
- }
-
- cursor_to (FRAME_HEIGHT (selected_frame) - 1, 0);
- clear_end_of_line (FRAME_WIDTH (selected_frame));
- /* clear_end_of_line may move the cursor */
- cursor_to (FRAME_HEIGHT (selected_frame) - 1, 0);
- }
-
- void amiga_consume_input(void)
- {
- extern int this_command_key_count;
- int force = this_command_key_count == 0;
- /* If force is TRUE & some non-keyboard (eg mouse events) input is pending,
- insert the appropriate magic sequence in the input stream */
-
- if (term_initialised)
- {
- #ifdef MULTI_FRAME
- CHFIXME check
- #endif
- if (!inhibit_window_system) check_window(selected_frame, force);
- else check_serial(force);
- check_arexx(force, TRUE);
- }
- }
-
- discard_tty_input ()
- {
- if (noninteractive)
- return;
-
- amiga_consume_input();
- tty_count = 0;
- chkabort();
- }
-
- /* Code for the fd describing the emacs input (terminal or window) */
-
- static ULONG __regargs ttyin_select_start(void *userinfo, int rd, int wr)
- {
- if (!inhibit_window_system) force_window(selected_frame);
-
- return (tty_count || mouse_event_pending()) ? -1 : inputsig;
- }
-
- static void __regargs ttyin_select_poll(void *userinfo, int *rd, int *wr)
- {
- amiga_consume_input();
- if (!tty_count && !mouse_event_pending()) *rd = 0;
- /* CHFIXME: evt. change interface, select will signal read ok on rd but
- that\'s no totally true (no chars) */
- }
-
- static int __regargs ttyin_read(void *userinfo, void *buffer, unsigned int length)
- {
- amiga_consume_input();
- if (length > tty_count) length = tty_count;
- memcpy(buffer, ttybuf, length);
- tty_count -= length;
- if (tty_count) memmove(ttybuf, ttybuf + length, tty_count - length);
- reset_mouse_event_pending();
-
- return (int)length;
- }
-
- static int __regargs ttyin_write(void *userinfo, void *buffer, unsigned int length)
- {
- errno = EACCES;
- return -1;
- }
-
- static int __regargs ttyin_lseek(void *userinfo, long rpos, int mode)
- {
- errno = ESPIPE;
- return -1;
- }
-
- static int __regargs ttyin_close(void *userinfo, int internal)
- {
- return 0;
- }
-
- static int __regargs ttyin_ioctl(void *userinfo, int request, void *data)
- {
- errno = EINVAL;
- return -1;
- }
-
- #define CBUFSIZE 1024
- #undef fwrite
- #undef fflush
-
- char cbuffer[CBUFSIZE + 16], *cbuffer_pos;
-
- int emacs_fflush(FILE *f)
- {
- if (noninteractive || f != stdout) return fflush(f);
- else
- {
- int len;
-
- len = cbuffer_pos - cbuffer;
- #ifdef MULTI_FRAME
- CHFIXME check
- #endif
- if (term_initialised)
- if (!inhibit_window_system) screen_puts(selected_frame, cbuffer, len);
- else serial_puts(cbuffer, len);
- if (termscript) fwrite (cbuffer, 1, len, termscript);
- cbuffer_pos = cbuffer;
-
- return 0;
- }
- }
-
- void emacs_putchar(int c)
- {
- if (cbuffer_pos >= cbuffer + CBUFSIZE) emacs_fflush(stdout);
- *cbuffer_pos++ = c;
- }
-
- void emacs_output(FRAME_PTR f, char *str, int size)
- {
- if (cbuffer_pos + size > cbuffer + CBUFSIZE) emacs_fflush(stdout);
- if (size > CBUFSIZE)
- {
- if (term_initialised)
- if (!inhibit_window_system) screen_puts(f, str, size);
- else serial_puts(str, size);
- }
- else
- {
- memcpy(cbuffer_pos, str, size);
- cbuffer_pos += size;
- }
- }
-
- void emacs_output_glyphs(FRAME_PTR f, GLYPH *str, int size) /* CHFIXME: we ignore faces for now */
- {
- if (cbuffer_pos + size > cbuffer + CBUFSIZE) emacs_fflush(stdout);
- if (size > CBUFSIZE)
- {
- register int i = size, lsize;
- register GLYPH *g = str;
-
- /* CHFIXME */
- while(i)
- {
- if(i < CBUFSIZE)
- lsize = i;
- else
- lsize = CBUFSIZE;
- emacs_output_glyphs(f, g, lsize);
- i -= lsize;
- g += lsize;
- }
- }
- else
- {
- register int i = size;
- register char *s = cbuffer_pos;
- register GLYPH *g = str;
-
- while(i--)
- {
- *s++ = (*g++) & 0xff;
- }
- cbuffer_pos += size;
- }
- }
-
- void emacs_fwrite(char *str, unsigned int nblocks, unsigned int len, FILE *f)
- {
- if (noninteractive || f != stdout) fwrite (str, nblocks, len, f);
- else
- {
- unsigned int size;
-
- if (nblocks == 1) size = len; /* Emacs always uses 1 "block" */
- else size = nblocks * len;
- #ifdef MULTI_FRAME
- CHFIXME check
- #endif
- emacs_output(selected_frame, str, size);
- }
- }
-
- void syms_of_amiga_tty(void)
- {
- syms_of_amiga_screen();
- syms_of_amiga_rexx();
- }
-
- void init_amiga_tty()
- {
- inputsig = 0;
- term_initialised = FALSE;
- init_amiga_rexx();
- }
-
- void cleanup_amiga_tty()
- {
- cleanup_amiga_rexx();
- cleanup_amiga_serial();
- cleanup_amiga_screen();
- }
-
- void early_amiga_tty()
- {
- cbuffer_pos = cbuffer;
- tty_count = 0;
- }
-
- void amiga_term_open(void)
- {
- inhibit_window_system ? init_amiga_serial() : init_amiga_screen();
- close(0);
- if (_alloc_fd((void *)1, FI_READ, ttyin_select_start, ttyin_select_poll, ttyin_read,
- ttyin_write, ttyin_lseek, ttyin_close, ttyin_ioctl) == 0)
- term_initialised = TRUE;
- else _fail("Failed to initialise I/O, no memory ?");
- }
-
- /* Set the logical window size associated with descriptor FD
- to HEIGHT and WIDTH. This is used mainly with ptys. */
-
- int
- set_window_size (fd, height, width)
- int fd, height, width;
- {
- return -1; /* CHFIXME: where used?, ok? */
- }
-